﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ZoneLine.Common;

namespace ZoneLine.Views
{
    public class DataGridD : DataGrid
    {
        public DataGridD()
        {

        }

        private IEnumerable _backValue;

        [Bindable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IEnumerable ItemsSourceD
        {
            get { return (IEnumerable)GetValue(ItemsSourceDp); }
            set
            {
                if (value != _backValue)
                {
                    _backValue = value;
                    InitDataGrid(value);
                }
                SetValue(ItemsSourceDp, value);
            }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsSourceDp =
            DependencyProperty.Register("ItemsSourceD", typeof(IEnumerable), typeof(DataGridD), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsBusyPropertyChanged));

        private static void IsBusyPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is DataGridD dgd)
            {
                dgd.ItemsSourceD = (IEnumerable)e.NewValue;
            }
        }

        public static Type GetElementType(IEnumerable enumerable)
        {
            if (enumerable == null)
            {
                return null;
            }
            // 如果enumerable是非泛型的IEnumerable，则直接返回Object类型
            if (enumerable is IEnumerable<object> ss)
            {
                return ss.FirstOrDefault()?.GetType();
            }

            // 如果enumerable是泛型的IEnumerable，尝试获取其泛型参数的类型
            Type enumerableType = enumerable.GetType();
            Type genericType = enumerableType.GetGenericArguments().FirstOrDefault();
            if (genericType != null)
            {
                return genericType;
            }

            // 如果上述都不成立，则尝试获取IEnumerable的第一个元素的类型
            var element = enumerable.Cast<object>().FirstOrDefault();
            return element?.GetType() ?? typeof(object);
        }

        private void InitDataGrid(IEnumerable value)
        {
            this.ItemsSource = null;
            var val = GetElementType(value);
            if (val != null)
            {
                var properties = val.GetProperties();

                List<DgColumnAttr> dgColumns = new List<DgColumnAttr>();

                foreach (var item in properties)
                {
                    var attrs = item.GetCustomAttributes(true);

                    foreach (var attr in attrs)
                    {
                        IValueConverter converter = null;
                        if (attr is DgColumnConvertAttr converterAttr)
                        {
                            converter = converterAttr.Converter;
                        }

                        if (attr is DgColumnAttr attrTemp)
                        {
                            attrTemp.PropertyName = item.Name;
                            dgColumns.Add(attrTemp);
                            if (item.PropertyType == typeof(DateTime))
                            {
                                attrTemp.Converter = new TimeConverter();
                            }
                            else if (converter != null)
                            {
                                attrTemp.Converter = converter;
                            }
                        }
                    }
                }

                dgColumns = dgColumns.OrderBy(p => p.Index).ToList();

                this.Columns.Clear();

                foreach (var item in dgColumns)
                {
                    if (item.Converter != null)
                    {
                        var column = new DataGridTextColumn() { Header = item.HeaderName, Binding = new Binding(item.PropertyName) { Converter = item.Converter } };
                        this.Columns.Add(column);
                    }
                    else
                    {
                        var column = new DataGridTextColumn() { Header = item.HeaderName, Binding = new Binding(item.PropertyName) };
                        this.Columns.Add(column);
                    }
                }

                this.ItemsSource = value;
            }

        }
    }

    public class TimeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && value is DateTime dt)
            {
                return dt.ToString("yyyy-MM-dd HH:mm:ss");
            }
            else
            {
                return value;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
